package xj.model.uml;

import static xj.model.uml.UMLModelConstants.ROLE_CLASS;
import static xj.model.uml.UMLModelConstants.ROLE_DATATYPE;
import static xj.model.uml.UMLModelConstants.ROLE_DIAGRAM;
import static xj.model.uml.UMLModelConstants.ROLE_PACKAGE;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class UMLPackage extends NamedElement {

  public UMLPackage() {
    this(null);
  }

  public UMLPackage(String name) {
    super(name);
  }

  public void addUMLDiagram(UMLDiagram dia) {
    if (dia != null) {
      diagrams.add(dia);
      addOwnedElement(dia, ROLE_DIAGRAM);
    }
  }

  public void removeUMLDiagram(UMLDiagram dia) {
    if (dia != null) {
      diagrams.remove(dia);
      removeOwnedElement(dia);
    }
  }

  public Set<UMLDiagram> getDiagrams() {
    return diagrams;
  }

  public void addUMLPackage(UMLPackage pkg) {
    if (pkg != null) {
      packages.add(pkg);
      addOwnedElement(pkg, ROLE_PACKAGE);
    }
  }

  public void removeUMLPackage(UMLPackage pkg) {
    if (pkg != null) {
      packages.remove(pkg);
      removeOwnedElement(pkg);
    }
  }

  public Set<UMLPackage> getPackages() {
    return packages;
  }

  public void addUMLClass(UMLClass cls) {
    if (cls != null) {
      classes.add(cls);
      addOwnedElement(cls, ROLE_CLASS);
    }
  }

  public void removeUMLClass(UMLClass cls) {
    if (cls != null) {
      classes.remove(cls);
      removeOwnedElement(cls);
    }
  }

  public Set<UMLClass> getUMLClasses() {
    return classes;
  }

  public void addDataType(DataType d) {
    if (d != null) {
      datatypes.add(d);
      addOwnedElement(d, ROLE_DATATYPE);
    }
  }

  public void removeDataType(DataType d) {
    if (d != null) {
      datatypes.remove(d);
      removeOwnedElement(d);
    }
  }

  public Set<DataType> getDataTypes() {
    return datatypes;
  }

  public UMLClass findClassByName(String name) {
    if (name != null) {
      Iterator<UMLClass> iter = classes.iterator();
      while (iter.hasNext()) {
	UMLClass c = iter.next();
	if (name.equals(c.getName())) {
	  return c;
	}
      }
    }
    return null;
  }

  @Override
  public String toString() {
    return "UMLPackage: name=" + name;
  }

  @Override
  public Object clone() throws CloneNotSupportedException {
    UMLPackage pkg = (UMLPackage) super.clone();

    pkg.diagrams = new HashSet<UMLDiagram>();
    Iterator<UMLDiagram> iter0 = diagrams.iterator();
    while (iter0.hasNext()) {
      UMLDiagram dia = iter0.next();
      pkg.addUMLDiagram((UMLDiagram) dia.clone());
    }

    pkg.packages = new HashSet<UMLPackage>();
    Iterator<UMLPackage> iter1 = packages.iterator();
    while (iter1.hasNext()) {
      UMLPackage p = iter1.next();
      pkg.addUMLPackage((UMLPackage) p.clone());
    }

    pkg.classes = new HashSet<UMLClass>();
    Iterator<UMLClass> iter2 = classes.iterator();
    while (iter2.hasNext()) {
      UMLClass c = iter2.next();
      pkg.addUMLClass((UMLClass) c.clone());
    }

    pkg.datatypes = new HashSet<DataType>();
    Iterator<DataType> iter3 = datatypes.iterator();
    while (iter3.hasNext()) {
      DataType t = iter3.next();
      pkg.addDataType((DataType) t.clone());
    }

    return pkg;
  }

  protected Set<UMLDiagram> diagrams = new HashSet<UMLDiagram>();

  protected Set<UMLPackage> packages = new HashSet<UMLPackage>();

  protected Set<UMLClass> classes = new HashSet<UMLClass>();

  protected Set<DataType> datatypes = new HashSet<DataType>();

}
